package com.shiwaixiangcun.monitor.service.impl;

import com.rabbit.spring.data.search.SearchOperator;
import com.rabbit.spring.data.search.Searchable;
import com.rabbit.spring.data.search.filter.SearchFilter;
import com.rabbit.spring.data.search.filter.SearchFilterHelper;
import com.shiwaixiangcun.core.domain.Dictionary;
import com.shiwaixiangcun.core.exceptions.MonkeyException;
import com.shiwaixiangcun.core.plugin.dto.MonkeyDto;
import com.shiwaixiangcun.core.repository.dictionary.DictionaryRepository;
import com.shiwaixiangcun.core.service.BaseServiceImpl;
import com.shiwaixiangcun.core.utils.MonkeyUtils;
import com.shiwaixiangcun.monitor.domain.SystemSetup;
import com.shiwaixiangcun.monitor.domain.User;
import com.shiwaixiangcun.monitor.repository.SystemSetupRepository;
import com.shiwaixiangcun.monitor.repository.UserRepository;
import com.shiwaixiangcun.monitor.security.SecurityUtils;
import com.shiwaixiangcun.monitor.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UserServiceImpl extends BaseServiceImpl<User, Long> implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private SystemSetupRepository systemSetupRepository;
    @Autowired
    private DictionaryRepository dictionaryRepository;

    @Override
    public void addUser(MonkeyDto monkeyDto) {
        User user = new User();
        buildUser(monkeyDto, user);
        user.setPassword(passwordEncoder.encode(monkeyDto.getString("password")));
        user.setOrganizationId(SecurityUtils.getCurrentUser().getOrganizationId());
        userRepository.save(user);
        saveSystemSetup(user);
    }

    private void saveSystemSetup(User user) {
        SystemSetup systemSetup = new SystemSetup();
        systemSetup.setPositioningSwitch(true);
        systemSetup.setUser(user);
        Dictionary dictionary = dictionaryRepository.findByValue(SystemSetup.DEFAULT_THEME_NAME);
        systemSetup.setTheme(dictionary);
        systemSetupRepository.save(systemSetup);
    }

    @Override
    public void updateUser(MonkeyDto monkeyDto) {
        Long staffId = monkeyDto.getLong("staffId");
        User user = userRepository.findOne(staffId);
        buildUser(monkeyDto, user);
        userRepository.save(user);
    }

    @Override
    public Page<User> getStaffList(Pageable pageable, String search) {
        Searchable searchable = Searchable.newSearchable();
        searchable.setPage(pageable);
//        searchable.addSort(Sort.Direction.DESC, "createTime");
//        searchable.addSort(Sort.Direction.DESC, "status");
        Sort.Order sortOrder = new Sort.Order(Sort.Direction.DESC, "createTime");
        Sort.Order modifiedOrder = new Sort.Order(Sort.Direction.DESC, "status");
        searchable.addSort(new Sort(modifiedOrder, sortOrder));
        if (MonkeyUtils.isNotEmpty(search)) {
            SearchFilter f1 = SearchFilterHelper.newCondition("number", SearchOperator.like, "%" + search + "%");
            SearchFilter f2 = SearchFilterHelper.newCondition("name", SearchOperator.like, "%" + search + "%");
            SearchFilter f3 = SearchFilterHelper.newCondition("phone", SearchOperator.like, "%" + search + "%");
            searchable.or(f1, f2, f3);
        }
        return userRepository.findAll(searchable);
    }

    @Override
    public void updateStatus(Long staffId) {
        User user = userRepository.findOne(staffId);
        if (user.getStatus()) {
            user.setStatus(false);
        } else {
            user.setStatus(true);
        }
        userRepository.save(user);
    }

    @Override
    public User findByName(String username) {
        return userRepository.findByName(username);
    }

    @Override
    public User findByPhone(String phone) {
        return userRepository.findByPhone(phone);
    }

    @Override
    public Page<User> getStaffObjectList(Pageable pageable, String search) {
        Searchable searchable = Searchable.newSearchable();
        searchable.setPage(pageable);
        searchable.addSearchFilter("status", SearchOperator.eq, true);
        if (MonkeyUtils.isNotEmpty(search)) {
            SearchFilter f1 = SearchFilterHelper.newCondition("number", SearchOperator.like, "%" + search + "%");
            SearchFilter f2 = SearchFilterHelper.newCondition("name", SearchOperator.like, "%" + search + "%");
            SearchFilter f3 = SearchFilterHelper.newCondition("phone", SearchOperator.like, "%" + search + "%");
            searchable.or(f1, f2, f3);
        }
        return userRepository.findAll(searchable);
    }

    @Override
    public void passwordModify(String oldPassword, String newPassword) {
        User user = SecurityUtils.getCurrentUser();
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new MonkeyException("原密码不正确");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        save(user);
    }

    private void buildUser(MonkeyDto monkeyDto, User user) {
        user.setNumber(monkeyDto.getString("number"));
        user.setName(monkeyDto.getString("name"));
        String idCard = monkeyDto.getString("idCard");
        if (MonkeyUtils.isNotEmpty(idCard)) {
            user.setIdCard(idCard);
        }
        String phone = monkeyDto.getString("phone");
        if (!MonkeyUtils.isMobile(phone)) {
            throw new MonkeyException("电话号码不正确");
        }
        User userByPhone = userRepository.findByPhone(phone);
        if (MonkeyUtils.isNotEmpty(user.getPhone())) {
            if (user.getPhone().equals(phone)) {
            } else {
                if (MonkeyUtils.isNotEmpty(userByPhone)) {
                    throw new MonkeyException("电话号码已被使用");
                }
            }
        } else {
            if (MonkeyUtils.isNotEmpty(userByPhone)) {
                throw new MonkeyException("电话号码已被使用");
            }
        }
        user.setPhone(phone);
    }
}
